#include "item/item.h"
#include "item/handle.h"
#include "OldGraphicsView/Palette.h"

#include <QStyleOptionGraphicsItem>
#include <QPainterPathStroker>
#include <QPainter>

namespace SymbolEditor
{

    Handle::Handle(GraphicsItem *parent):
        QGraphicsPathItem(parent),
        IObservableItem(),
        m_role(Role::Move),
        m_handleShape(Shape::Circle)
    {
        setPen(QPen(m_palette.primaryContent(), 0));
        setBrush(QBrush(m_palette.background()));

        setFlag(QGraphicsItem::ItemIsMovable);
        setFlag(QGraphicsItem::ItemSendsGeometryChanges);
        setFlag(QGraphicsItem::ItemIgnoresTransformations);
        setFlag(QGraphicsItem::ItemIgnoresParentOpacity);

        updateShape();

        setVisible(false);
    }

    Handle::~Handle()
    {

    }

    QCursor Handle::handleCursor() const
    {
        return roleToCursor(m_role);
    }

    void Handle::setHandleId(int id)
    {
        m_id = id;
    }

    int Handle::handleId() const
    {
        return m_id;
    }

    void Handle::setHandleRole(Role role)
    {
        if (m_role == role)
        {
            return;
        }

        prepareGeometryChange();
        m_role = role;
        update();
    }

    Handle::Role Handle::handleRole() const
    {
        return m_role;
    }

    void Handle::setHandleShape(Shape shape)
    {
        if (m_handleShape == shape)
        {
            return;
        }

        m_handleShape = shape;

        updateShape();
    }

    Handle::Shape Handle::handleShape() const
    {
        return m_handleShape;
    }

    void Handle::setPalette(LeGraphicsView::Palette palette)
    {
        m_palette = palette;
        setPen(QPen(m_palette.primaryContent(), 0));
        setBrush(QBrush(m_palette.background()));
        update();
    }

    LeGraphicsView::Palette Handle::palette() const
    {
        return m_palette;
    }

    QCursor Handle::roleToCursor(Role role)
    {
        switch (role)
        {
            case Role::Move:
                return QCursor(Qt::PointingHandCursor);
            case Role::VSize:
                return QCursor(Qt::SizeVerCursor);
            case Role::HSize:
                return QCursor(Qt::SizeHorCursor);
            case Role::BDiagSize:
                return QCursor(Qt::SizeBDiagCursor);
            case Role::FDiagSize:
                return QCursor(Qt::SizeFDiagCursor);
            case Role::Rotate:
                return QCursor(); // TBD
            case Role::Shear:
                return QCursor();  // TBD
            case Role::Mark:
                return QCursor();   // TBD
            default:
                return QCursor();
        }
    }

    void Handle::updateShape()
    {
        int radius = 5;
        QPainterPath path;
        switch (m_handleShape)
        {
            case Shape::Circle:
            {
                radius *= 0.97;
                path.addEllipse(QPointF(0, 0), radius, radius);
                break;
            }
            case Shape::Square:
            {
                radius *= 0.8;
                path.addRect(-radius, -radius, 2 * radius, 2 * radius);
                break;
            }
            case Shape::Diamond:
            {
                QVector<QPointF> points;
                points << QPointF(0, -radius) << QPointF(radius, 0)
                       << QPointF(0, radius) << QPointF(-radius, 0);
                path.addPolygon(QPolygonF(points));
                path.closeSubpath();
                break;
            }
            default:
                // Not reached
                break;
        }
        setPath(path);
    }


    QVariant Handle::itemChange(QGraphicsItem::GraphicsItemChange change,
                                const QVariant &value)
    {
        if (change == QGraphicsItem::ItemPositionHasChanged)
        {
            notifyObservers();
        }
        return value;
    }

}
